package jmine.tec.web.wicket.pages.form;

import java.util.ArrayList;
import java.util.List;

import jmine.tec.web.wicket.component.button.ActionSubmitLink;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.extensions.markup.html.tabs.TabbedPanel;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.Model;

import bancosys.tec.persist.Persistable;

/**
 * Implementação base de uma página de inclusão/visualização e edição de entidades com abas.
 * 
 * @author Gallardo
 * @param <BO> tipo da entidade
 */
public abstract class FormPageTabbed<BO extends Persistable> extends FormPage<BO> {

    /**
     * Construtor para a criação de uma nova entidade.
     * 
     * @param pageParameters {@link PageParameters}
     */
    public FormPageTabbed(PageParameters pageParameters) {
        super(pageParameters);
    }

    /**
     * Construtor para a criação de uma nova entidade.
     * 
     * @param sourcePageParameters {@link PageParameters}
     * @param source página de origem
     */
    public FormPageTabbed(Class<? extends Page> source, PageParameters sourcePageParameters) {
        super(source, sourcePageParameters);
    }

    /**
     * Construtor.
     * 
     * @param source página de origem
     * @param sourcePageParameters page parameters da pagina de origem
     * @param entity entidade que deve ser associado a página
     * @param formType tipo do formulario da página
     */
    public FormPageTabbed(Class<? extends Page> source, PageParameters sourcePageParameters, BO entity, FormType formType) {
        super(source, sourcePageParameters, entity, formType);
    }

    /**
     * Retorna a lista de componentes que devem ser adicionados no formulário.
     * 
     * @return a lista de componentes que devem ser adicionados no formulário
     */
    @Override
    protected final List<Component> createFormComponents() {
        List<Component> components = this.createMainFormComponents();
        components.addAll(this.createTabbedPanels());
        return components;
    }

    /**
     * Cria um panel com as abas passadas no parâmetro.
     * 
     * @param panelId o id do panel.
     * @param tabs a lista de abas.
     * @return um panel com as abas passadas no parâmetro.
     */
    protected TabbedPanel createTabbedPanel(String panelId, List<ITab> tabs) {
        return new CustomTabbedPanel(panelId, tabs);
    }

    /**
     * Adiciona campos que não estarão nas abas. Fazer Override se desejado.
     * 
     * @return lista de campos que não estarão nas abas.
     */
    protected List<Component> createMainFormComponents() {
        return new ArrayList<Component>();
    }

    /**
     * Obtém os painéis com abas que farão parte do cadastro.
     * 
     * @return lista de TabbedPanel.
     */
    protected abstract List<TabbedPanel> createTabbedPanels();

    /**
     * Percorre array de componentes e desabilita apenas os que tem identificação diferente de "tab"
     * 
     * @param disableField condição para desabilitar o campo.
     * @param ro read-only para textfields.
     * @param disabled desabilita componentes como combobox.
     * @param component o componente.
     */
    @Override
    protected void disableComponent(boolean disableField, AttributeModifier ro, AttributeModifier disabled, Component component) {
        if (component instanceof FormPageTabbed.CustomTabbedPanel) {
            ((FormPageTabbed.CustomTabbedPanel) component).disableContents();
        } else {
            super.disableComponent(disableField, ro, disabled, component);
        }
    }

    /**
     * @author wellington.santos
     */
    protected class CustomTabbedPanel extends TabbedPanel {

        /**
         * Construtor para a criação de CustomTabPanel.
         * 
         * @param id id do painel-container de abas
         * @param tabs lista de abas do painel
         */
        public CustomTabbedPanel(String id, List<ITab> tabs) {
            super(id, tabs);
            if (FormPageTabbed.this.getFormType().isView()) {
                this.setSelectedTab(0);
            }
        }

        /**
         * {@inheritDoc}
         *
         * @return {@inheritDoc}
         */
        @Override
        protected WebMarkupContainer newLink(String linkId, final int index) {
            return new ActionSubmitLink(linkId) {
                @Override
                public void onAction() {
                    CustomTabbedPanel.this.setSelectedTab(index);
                    if (FormPageTabbed.this.getFormType().isView()) {
                        CustomTabbedPanel.this.disableContents();
                    }
                }
            };
        }

        /**
         * desabilita os conteudos das abas
         */
        private void disableContents() {
            Component tabContent = this.get(TAB_PANEL_ID);
            if (tabContent != null && tabContent.isEnabled()) {
                AttributeModifier ro = new AttributeModifier("readonly", true, new Model<String>("readonly"));
                AttributeModifier disabled = new AttributeModifier("disabled", true, new Model<String>("disabled"));
                tabContent.add(ro).add(disabled).setEnabled(false);
            }
        }
    }

}
